package com.vip.jwt.websocket;

import cn.hutool.json.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Component
@ServerEndpoint("/websocket/{id}")
public class WebSocketService {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketService.class);

    private static Map<Integer, Session> sessionMap = new HashMap<>(16);

    /**
     * 存储客户端Session
     * @param id
     * @param session
     */
    public void setSession(Integer id, Session session) {
        sessionMap.put(id, session);
    }

    /**
     * 获取客户端Session
     * @param id
     * @return
     */
    public Session getSession(Integer id) {
        return sessionMap.get(id);
    }

    /**
     * 移除客户端Session
     * @param id
     */
    public void removeSession(Integer id) {
        sessionMap.remove(id);
    }

    /**
     * 发送消息
     *
     * @param id
     * @param message
     */
    public void sendMessage(Integer id, String message) {
        Session session = getSession(id);
        if(null!=session){
            try {
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                logger.error("WebSocket发送消息异常:用户ID为"+id+"的用户不在线");
            }
        }
    }

    /**
     * 广播新消息
     */
    public void broadCastMessage(Object message) {
        Set<Map.Entry<Integer, Session>> entries = sessionMap.entrySet();
        entries.parallelStream().forEach(v -> {
            sendMessage(v.getKey(), JSONUtil.toJsonStr(message));
        });
    }

    /**
     * 连接成功
     * @param id
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("id") Integer id, Session session) {
        logger.info("连接成功");
        setSession(id, session);
    }

    /**
     * 接收客户端消息
     * @param id
     * @param message
     */
    @OnMessage
    public void onMessage(@PathParam("id") Integer id, String message) {
        logger.info("接收来自["+id+"]的消息："+message);
    }

    /**
     * 关闭连接
     * @param id
     * @param session
     */
    @OnClose
    public void onClose(@PathParam("id") Integer id, Session session) {
        /**
         * 关闭Session
         */
        try {
            logger.info("关闭连接");
            session.close();
            removeSession(id);
        } catch (IOException e) {
            logger.error("关闭连接", e);
        }
    }

    /**
     * 连接异常
     * @param id
     * @param session
     * @param throwable
     */
    @OnError
    public void onError(@PathParam("id") Integer id, Session session, Throwable throwable) {
        /**
         * 关闭Session
         */
        try {
            session.close();
            logger.info("关闭连接");
            removeSession(id);
        } catch (IOException e) {
            logger.error("出现错误：", e);
        }
        logger.info("错误信息： " + throwable.getMessage());
    }

}
